<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket 客户端</title>
    <style>
        /* 页面全局字体和边距 */
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }

        /* 所有输入框、按钮、文本域统一间距 */
        input, button, textarea {
            margin: 5px 0;
        }

        /* WebSocket 地址输入框宽度和内边距 */
        #path {
            width: 500px;
            padding: 5px;
        }

        /* 消息输入框宽度和内边距 */
        #msg {
            width: 400px;
            padding: 5px;
        }

        /* 消息显示文本域样式：固定大小、等宽字体便于对齐 */
        #text {
            width: 500px;
            height: 300px;
            padding: 5px;
            font-family: monospace; /* 等宽字体，适合日志显示 */
        }

        /* 按钮通用样式 */
        button {
            padding: 5px 10px;
            cursor: pointer; /* 鼠标悬停显示手型 */
        }

        /* 连接按钮背景色：蓝色系 */
        .connect-btn {
            background-color: #00bcd4;
        }

        /* 断开连接按钮：红色系 + 白字 */
        .disconnect-btn {
            background-color: #f44336;
            color: white;
        }

        /* 清空按钮：橙色系 + 白字 */
        .clear-btn {
            background-color: #ff9800;
            color: white;
        }
    </style>
</head>
<body>
<!-- 页面标题 -->
<h2>WebSocket 客户端</h2>

<!-- WebSocket 服务地址输入区域 -->
<label>WebSocket 地址：</label><br>
<input type="text" id="path" placeholder="例如：ws://localhost:10000/ws/100" value="ws://localhost:10000/ws/100"><br>

<!-- 操作按钮组：连接、断开、清空 -->
<button onclick="openConn()" class="connect-btn">连接</button>
<button onclick="closeConn()" class="disconnect-btn">断开连接</button>
<button onclick="clearTextArea()" class="clear-btn">清空消息</button>
<br><br>

<!-- 消息日志显示区域（只读） -->
<textarea id="text" readonly></textarea><br>

<!-- 消息输入框 + 发送按钮 -->
<input type="text" id="msg" placeholder="输入消息...">
<button onclick="send()">发送</button>

<script>
    // 全局变量：WebSocket 实例，初始为 null
    let ws = null;

    // 获取文本域元素，用于显示通信日志
    const textArea = document.getElementById('text');

    // 页面加载时清空文本域（初始化）
    textArea.value = '';

    /**
     * 日志输出函数：向文本域追加消息并自动滚动到底部
     * @param {string} msg - 要显示的消息内容
     */
    function log(msg) {
        textArea.value += msg + '\n'; // 追加消息 + 换行
        textArea.scrollTop = textArea.scrollHeight; // 自动滚动到最新消息
    }

    /**
     * 建立 WebSocket 连接
     * 从输入框读取地址，创建 WebSocket 实例并绑定事件
     */
    function openConn() {
        // 获取用户输入的 WebSocket 地址并去除首尾空格
        const path = document.getElementById('path').value.trim();

        // 校验：地址不能为空
        if (!path) {
            alert('请输入 WebSocket 地址');
            return;
        }

        // 校验：避免重复连接
        if (ws && ws.readyState === WebSocket.OPEN) {
            log('客户端: 已连接，无需重复连接');
            return;
        }

        // 创建 WebSocket 实例
        ws = new WebSocket(path);

        // 连接成功回调
        ws.onopen = function () {
            log('客户端: 与服务端建立了链接');
            ws.send('Hello'); // 自动发送打招呼消息
            log('客户端: 发送 -> Hello');
        };

        // 收到服务端消息回调
        ws.onmessage = function (e) {
            log('服务器端: ' + e.data); // 显示服务端返回内容
            console.log('收到服务器响应:', e.data); // 控制台也打印，便于调试
        };

        // 连接关闭回调
        ws.onclose = function () {
            log('客户端: 连接已关闭');
        };

        // 连接错误回调
        ws.onerror = function (err) {
            log('客户端: 连接发生错误: ' + err.message);
            console.error('WebSocket 错误:', err); // 控制台打印错误详情
        };
    }

    /**
     * 发送消息到服务端
     * 校验连接状态和消息内容，发送后清空输入框
     */
    function send() {
        // 校验：WebSocket 是否已连接
        if (!ws || ws.readyState !== WebSocket.OPEN) {
            alert('请先连接 WebSocket 服务');
            return;
        }

        // 获取用户输入的消息并去除首尾空格
        const msg = document.getElementById('msg').value.trim();

        // 校验：消息不能为空
        if (!msg) {
            alert('消息不能为空');
            return;
        }

        // 发送消息
        ws.send(msg);
        log('客户端: 发送 -> ' + msg); // 记录到日志

        // 清空输入框，提升用户体验
        document.getElementById('msg').value = '';
    }

    /**
     * 主动关闭 WebSocket 连接
     */
    function closeConn() {
        // 校验：只有在已连接状态下才允许关闭
        if (ws && ws.readyState === WebSocket.OPEN) {
            ws.close(); // 发起关闭请求
            log('客户端: 正在关闭连接...');
        } else {
            log('客户端: 当前未连接');
        }
    }

    /**
     * 清空消息日志文本域
     */
    function clearTextArea() {
        textArea.value = '';
    }

    /*
     * 可选功能：页面加载完成后自动连接（开发调试时可用）
     * 取消注释下面一行即可启用
     */
    // window.onload = openConn;

</script>
</body>
</html>